package com.ruoyi.project.fusion.algorithms;

import com.ruoyi.project.fusion.domain.QualityAggInfo;
import com.ruoyi.project.fusion.domain.QualityScores;
import com.ruoyi.project.fusion.utils.ComputeUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class QualityAlgorithm {
    public List<QualityScores> compute(List<QualityAggInfo> qualityAggInfos) {
        List<QualityScores> scoresList = new ArrayList<>();

        // 按照 chainType、scenario、product 分组
        Map<List<String>, List<QualityAggInfo>> groupedInfos = qualityAggInfos.stream()
                .collect(Collectors.groupingBy(info -> Arrays.asList(
                        info.getChainType(),
                        info.getScenario(),
                        info.getProduct(),
                        info.getEvent()
                )));

        for (Map.Entry<List<String>, List<QualityAggInfo>> entry : groupedInfos.entrySet()) {
            List<QualityAggInfo> group = entry.getValue();

            // 归一化数据
            List<Double> normalizedEquipmentFailureRate = ComputeUtils.normalizeValues(group.stream().map(QualityAggInfo::getAvgEquipmentFailureRate).collect(Collectors.toList()));
            List<Double> normalizedQualityCheckPassRate = ComputeUtils.normalizeValues(group.stream().map(QualityAggInfo::getAvgQualityCheckPassRate).collect(Collectors.toList()));
            List<Double> normalizedQualityCertificateCount = ComputeUtils.normalizeValues(group.stream().map(QualityAggInfo::getAvgQualityCertificateCount).collect(Collectors.toList()));
            List<Double> normalizedNewProductDevelopmentCycle = ComputeUtils.normalizeValues(group.stream().map(QualityAggInfo::getAvgNewProductDevelopmentCycle).collect(Collectors.toList()));
            List<Double> normalizedPatentCount = ComputeUtils.normalizeValues(group.stream().map(QualityAggInfo::getAvgPatentCount).collect(Collectors.toList()));

            // 计算各项指标的标准差
            double stdDevEquipmentFailureRate = ComputeUtils.calculateStandardDeviation(normalizedEquipmentFailureRate);
            double stdDevQualityCheckPassRate = ComputeUtils.calculateStandardDeviation(normalizedQualityCheckPassRate);
            double stdDevQualityCertificateCount = ComputeUtils.calculateStandardDeviation(normalizedQualityCertificateCount);
            double stdDevNewProductDevelopmentCycle = ComputeUtils.calculateStandardDeviation(normalizedNewProductDevelopmentCycle);
            double stdDevPatentCount = ComputeUtils.calculateStandardDeviation(normalizedPatentCount);

            // 计算总标准差
            double totalStdDev = stdDevEquipmentFailureRate + stdDevQualityCheckPassRate + stdDevQualityCertificateCount + stdDevNewProductDevelopmentCycle + stdDevPatentCount;

            // 计算权重
            double weightEquipmentFailureRate = (totalStdDev == 0) ? 0.2 : stdDevEquipmentFailureRate / totalStdDev;
            double weightQualityCheckPassRate = (totalStdDev == 0) ? 0.2 : stdDevQualityCheckPassRate / totalStdDev;
            double weightQualityCertificateCount = (totalStdDev == 0) ? 0.2 : stdDevQualityCertificateCount / totalStdDev;
            double weightNewProductDevelopmentCycle = (totalStdDev == 0) ? 0.2 : stdDevNewProductDevelopmentCycle / totalStdDev;
            double weightPatentCount = (totalStdDev == 0) ? 0.2 : stdDevPatentCount / totalStdDev;

            // 计算分数
            for (int i = 0; i < group.size(); i++) {
                QualityAggInfo info = group.get(i);

                double score = (normalizedEquipmentFailureRate.get(i) * weightEquipmentFailureRate) +
                        (normalizedQualityCheckPassRate.get(i) * weightQualityCheckPassRate) +
                        (normalizedQualityCertificateCount.get(i) * weightQualityCertificateCount) +
                        (normalizedNewProductDevelopmentCycle.get(i) * weightNewProductDevelopmentCycle) +
                        (normalizedPatentCount.get(i) * weightPatentCount);

                QualityScores qualityScore = new QualityScores();
                qualityScore.setChainType(info.getChainType());
                qualityScore.setEnterpriseName(info.getEnterpriseName());
                qualityScore.setScenario(info.getScenario());
                qualityScore.setProduct(info.getProduct());
                qualityScore.setEvent(info.getEvent());
                qualityScore.setScore(ComputeUtils.roundToTwoDecimalPlaces((float) score));

                scoresList.add(qualityScore);
            }
        }

        return scoresList;
    }
}
